﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace P
{
    /// <summary>
    /// 对象帮助类
    /// </summary>
    public class ObjectHelper
    {
        /// <summary>
        /// 根据对象属性名修改对象对应属性值，用于对象拷贝，后边的值给前边
        /// </summary>
        /// <param name="propertyName">属性名</param>
        /// <param name="value1">待修改对象</param>
        /// <param name="value2">修改后的对象</param>
        public void SetPropertyHelper(string propertyName, object value1, object value2)
        {
            var s = value1.GetType().GetProperty(propertyName);
            if (s == null)
                return;
            value1.GetType().GetProperty(propertyName).SetValue(value1, value2.GetType().GetProperty(propertyName).GetValue(value2, null));
        }
        /// <summary>
        /// 根据属性名取值
        /// </summary>
        /// <param name="propertyName"></param>
        /// <param name="o"></param>
        /// <returns></returns>
        public object GetValueByProtertyName(string propertyName,object o)
        {
            Type type = o.GetType();
            var temp = type.GetProperty(propertyName, (System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance));
            if (temp != null)
            {
                return temp.GetValue(o);
            }
            return null;
        }
        /// <summary>
        /// 根据字段名获取值
        /// </summary>
        /// <param name="fieldName"></param>
        /// <param name="o"></param>
        /// <returns></returns>
        public object GetValueByFieldName(string fieldName, object o)
        {
            Type type = o.GetType();
            var temp = type.GetField(fieldName, (System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance));
            if (temp != null)
            {
                return temp.GetValue(o);
            }
            return null;
        }
        /// <summary>
        /// 根据方法名调用方法
        /// </summary>
        /// <param name="medthodName">方法名</param>
        /// <param name="o">对象名</param>
        /// <param name="pars">参数集合</param>
        /// <returns></returns>
        public object InvokMedthod(string medthodName,object o,object[] pars)
        {
            Type type = o.GetType();
            var temp = type.GetMethod(medthodName, (System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance));
            return temp.Invoke(o, pars);
        }
        /// <summary>
        /// 对象克隆（深克隆，目前数组Array无法克隆，其他的都OK）
        /// </summary>
        /// <param name="newObj">目标对象</param>
        /// <param name="oldObj">源对象</param>
        /// <returns></returns>
        public bool ObjectClone(object newObj, object oldObj)
        {
            if (newObj == null || oldObj == null)
            {
                return false;
            }
            ListHelper listHelper = new ListHelper();
            Type newType = newObj.GetType();
            Type oldType = oldObj.GetType();
            if (newType == oldType)
            {
                if (oldType.GetProperties().Length == 0)
                {
                    return false;
                }
                //循环取属性
                foreach (var item in newType.GetProperties())
                {
                    var oldValue = item.GetValue(oldObj);
                    if (oldValue == null)
                    {
                        continue;
                    }
                    //值类型直接赋值
                    if (oldValue is string || oldValue.GetType().GetProperties().Length == 0)
                    {
                        item.SetValue(newObj, oldValue);
                    }
                    //集合的话，调用集合的克隆方法
                    else if (oldValue is ArrayList || oldValue.GetType().GetMethod("GetEnumerator") != null)
                    {
                        //数组处理不了，跳出本次循环
                        if (oldValue is Array)
                        {
                            continue;
                        }
                        else
                        {
                            //初始化
                            item.SetValue(newObj, System.Activator.CreateInstance(oldValue.GetType()));
                            listHelper.ListClone(item.GetValue(newObj), oldValue);
                        }

                    }
                    //如果是引用类型，也就是对象，则调用对象的克隆方法，也需要先初始化操作
                    else
                    {
                        if (item.GetValue(newObj) == null)
                        {
                            item.SetValue(newObj, System.Activator.CreateInstance(oldValue.GetType()));
                        }
                        ObjectClone(item.GetValue(newObj), item.GetValue(oldObj));
                    }
                }

                return true;
            }
            return false;
        }
    }
}
